import {
  Body,
  Controller,
  Del,
  Get,
  Inject,
  Param,
  Post,
  Put
} from '@midwayjs/core'
import { Context } from '@midwayjs/koa'
import {
  ApiBearerAuth,
  ApiOperation,
  ApiResponse,
  ApiTags
} from '@midwayjs/swagger'
import { Validate } from '@midwayjs/validate'
import { ExcelService } from '@ttou/midway-excel'

import { CACHE_KEYS } from '@/constant'
import { Permission } from '@/decorator'
import { DeleteDTO } from '@/dto'
import { CacheMiddleware } from '@/middleware'

import {
  CreateConfigDTO,
  FindConfigPageDTO,
  UpdateConfigDTO
} from './config.dto'
import { ConfigExportSerialize } from './config.serialize'
import { ConfigService } from './config.service'
import { GetConfigPageVO, GetConfigValueVO } from './config.vo'

@ApiBearerAuth()
@ApiTags('系统/配置接口')
@Controller('/system/config')
export class ConfigController {
  @Inject()
  ctx: Context

  @Inject()
  configService: ConfigService

  @Inject()
  excelService: ExcelService

  @ApiOperation({ summary: '获取配置分页' })
  @ApiResponse({ status: 200, type: GetConfigPageVO })
  @Permission('system:config:list')
  @Post('/page')
  @Validate()
  async getConfigPage(@Body() dto: FindConfigPageDTO) {
    return await this.configService.handleFindPage(dto)
  }

  @ApiOperation({ summary: '获取配置值' })
  @ApiResponse({ status: 200, type: GetConfigValueVO })
  @Get('/configKey/:key', {
    middleware: [
      CacheMiddleware({
        key: ctx => `${CACHE_KEYS.SYS_CONFIG_KEY}${ctx.params.key}`,
        ttl: 15 * 1000
      })
    ]
  })
  async getConfigValue(@Param('key') key: string) {
    return await this.configService.handleGetValue(key)
  }

  @ApiOperation({ summary: '新增配置' })
  @Permission('system:config:add')
  @Post('/create')
  @Validate()
  async createConfig(@Body() dto: CreateConfigDTO) {
    await this.configService.handleCreate(dto)
  }

  @ApiOperation({ summary: '更新配置' })
  @Permission('system:config:edit')
  @Put('/update/:id')
  @Validate()
  async updateConfig(@Param('id') id: string, @Body() dto: UpdateConfigDTO) {
    await this.configService.handleUpdate(id, dto)
  }

  @ApiOperation({ summary: '删除配置' })
  @Permission('system:config:remove')
  @Del('/delete')
  @Validate()
  async deleteConfig(@Body() dto: DeleteDTO) {
    await this.configService.handleDelete(dto)
  }

  @ApiOperation({ summary: '导出配置分页' })
  @Permission('system:config:export')
  @Post('/export')
  @Validate()
  async exportConfigPage(@Body() dto: FindConfigPageDTO) {
    const { list } = await this.configService.handleFindPage(dto)

    const result = await this.excelService.handleExport({
      sheetName: '配置',
      filename: '配置报表',
      Cls: ConfigExportSerialize,
      data: list
    })

    this.ctx.set(result.headers)
    this.ctx.body = result.body
  }
}
